package com.igame.garbage;


import java.net.URL;

import javax.swing.ImageIcon;

import com.jme.image.Texture;
import com.jme.input.ChaseCamera;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.input.RelativeMouse;
import com.jme.input.action.MouseLook;
import com.jme.input.controls.binding.MouseButtonBinding;
import com.jme.light.DirectionalLight;
import com.jme.math.*;

import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.WireframeState;
import com.jme.scene.state.ZBufferState;
import com.jme.scene.state.BlendState.TestFunction;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
public class Tryjme extends BaseGame {
//	public static void main(String[] args){
//		try{
//			BaseGame bg = new Tryjme();
//			//bg.setConfigShowMode(ConfigShowMode.AlwaysShow);
//			bg.start();
//		}catch(Exception e){
//			System.out.println(e.toString());
//		}
//	}

	@Override
	protected void cleanup() {
		// TODO Auto-generated method stub
	}
	
	//terrain block object
	private TerrainBlock tb;
	private void buildTerrain(){
		//create height map
		MidPointHeightMap mp = new MidPointHeightMap(64, 1f);
		Vector3f tbscale = new Vector3f(20,0.5f,20);
		
		//create terrain block
		if(tb==null){
			tb = new TerrainBlock("terrain", mp.getSize(), tbscale, mp.getHeightMap(), Vector3f.ZERO);
		}
		tb.setModelBound(new BoundingBox());
		tb.updateModelBound();
//		ProceduralTextureGenerator pt = new ProceduralTextureGenerator(mp);
//		URL txurl = this.getClass().getClassLoader().getResource("resource/simplemap.png");
//		pt.addTexture(new ImageIcon(txurl), 128, 200, 255);
//		pt.createTexture(32);
//		
//		//assign texture
//		TextureState ts = display.getRenderer().createTextureState();
//		ts.setEnabled(true);
//		Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(), 
//				Texture.MinificationFilter.Trilinear,
//				Texture.MagnificationFilter.Bilinear,
//				true);
//		ts.setTexture(t1);
//		tb.setRenderState(ts);
	}
	
	private void initLighting(){
		DirectionalLight dl = new DirectionalLight();
		dl.setDiffuse(new ColorRGBA(1,1,1,1));
		dl.setAmbient(new ColorRGBA(0.5f,0, 0, 1));
		dl.setDirection(new Vector3f(1,-1,0));
		dl.setEnabled(true);
		
		LightState ls = display.getRenderer().createLightState();
		ls.setEnabled(true);
		ls.attach(dl);
		scene.setRenderState(ls);
	}

	private Node scene;
	@Override
	protected void initGame() {
		scene = new Node("RootNode");
		
		display.getRenderer().setBackgroundColor(ColorRGBA.black);
		ZBufferState zbs = display.getRenderer().createZBufferState();
		zbs.setEnabled(true);
		zbs.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
		scene.setRenderState(zbs);
		
		//create a sphere
		Sphere s=new Sphere("mysphere",30,30,25);
		//s.setLocalScale(2.0f);
		s.setLocalTranslation(0, 0, 0);
		//s.setModelBound(new );
		//s.setModelBound(new com.jme.bounding.BoundingBox());
		//s.updateModelBound();
		
		//create a texture
		TextureState ts = display.getRenderer().createTextureState();
		ts.setEnabled(true);
		ts.setTexture(TextureManager.loadTexture(
				Tryjme.class.getClassLoader().getResource("resource/simplemap.png")));
		
		//attach texture to object
		s.setRenderState(ts);
		scene.attachChild(s);
		
		buildTerrain();
//		Node tbnode = new Node("tbnode");
//		tbnode.setLocalTranslation(-40, 0, 0);
//		tbnode.attachChild(tb);
//		scene.attachChild(tbnode);
		scene.attachChild(tb);
		
		WireframeState rs = display.getRenderer().createWireframeState();
		rs.setEnabled(true);
		rs.setLineWidth(1.5f);
		//tbnode.setRenderState(rs);
		scene.setRenderState(rs);
		
		//update the scene graph for rendering
		initLighting();
		scene.updateGeometricState(0, true);
		scene.updateRenderState();
	}

	private int width,height,depth,freq;
	private boolean fullscreen;
	private Camera cam;
	private Timer timer;
	
	@Override
	protected void initSystem() {
		// TODO Auto-generated method stub
		width = settings.getWidth();
		height = settings.getHeight();
		depth = settings.getDepth();
		freq = settings.getFrequency();
		fullscreen = settings.isFullscreen();
		
		try {
			display = DisplaySystem.getDisplaySystem(settings.getRenderer());
			display.createWindow(width, height, depth, freq, fullscreen);
			cam = display.getRenderer().createCamera(width, height);
		} catch(JmeException e){
			e.printStackTrace();
			System.exit(1);
		}
		
		//init camera
		cam.setFrustumPerspective(45.0f, (float)width/(float)height, 1, 1000);
		//camera axis
		Vector3f loc = new Vector3f(0,0,40);
		Vector3f left = new Vector3f(-1,1,0); //-x axis
		Vector3f up = new Vector3f(1,1,0); //+y axis
		Vector3f dir = new Vector3f(0,0,-1); //looking to -z axis
		cam.setFrame(loc, left, up, dir);
		cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
		cam.update();
		
		//timer set up
		timer = Timer.getTimer();
		
		//attach camera to render system
		display.getRenderer().setCamera(cam);
		//set up default key binding
		KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
	}

	@Override
	protected void reinit() {
		// TODO Auto-generated method stub
		display.recreateWindow(width, height, depth, freq, fullscreen);
	}

	@Override
	protected void render(float interpolation) {
		// TODO Auto-generated method stub
		
		//clear the screen
		//what for? new image won't overwrite the old one?
		display.getRenderer().clearBuffers();
		display.getRenderer().draw(scene);
	}

	private double dt = Math.PI/10;
	private double radius = 40;
	private double t = 0;
	private double hy = 200;
	protected void update(float interpolation) {
		// TODO Auto-generated method stub
		timer.update();
		
		//what's for?
		interpolation = timer.getTimePerFrame();
		
		if(t > 2*Math.PI){
			t -= 2*Math.PI;
		}
		
		double thisdt = dt * interpolation;
		t += thisdt;
		Vector3f camloc = new Vector3f( (float)(radius*Math.cos(t)), (float)hy, (float)(radius*Math.sin(t)) );
		cam.setLocation(camloc);
		cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
		cam.update();
		
		//check for escape
		if(KeyBindingManager.getKeyBindingManager().isValidCommand("exit")){
			finished = true; //modifying superclass variable
		}
	}
}
